解析DSSD对象机制:内存API Atomic读写再现
在2月的最后一天,EMC终于正式发布了DSSD。由于在此之前,国内友商早已迫不及待地“泄露”了相关资料,留意这方面的朋友估计对DSSD的硬件架构和主要特点已经有所了解。包括PCIe交换架构、冗余组件、RAID保护这些确实是基础,而软件才是DSSD D5 RACK-SCALE 闪存存储平台真正的灵魂,这就是本文要讨论的内容。
注:由于我的技术水平有限,本文中如有错误和不足之处欢迎批评指正。
两种Two DSSD对象,一种512B片段长度和另一种4K片段长度
我们知道DSSD的原生访问API是对象方式,同时兼容块、文件以及像Hadoop这样的专用插件。上图示意了2个不同帧长度(分片大小)的对象,DSSD支持的对象片段在64 bytes到 32 KB之间,而DRAM内存最小操作单元页面的大小也是64 bytes,这样我们可以理解DSSD为什么适合In-Memory应用了吧?
上图截自EMC的specsheet,DSSD就是专为(大)数据分析而生的
其实64 bytes还让我想起以前企业级闪存领域一个著名的品牌,在后文中会有交待,这里先留一个伏笔:)
原生API DMA访问和PCIe MultiCast写入
通过libflood API从客户端系统应用的读操作
如上图,用户从客户端使用原生API读取DSSD时,数据流是绕过OS Kernel的DMA方式。而且数据是从Flash Module上的DRAM缓存经过I/O Module直接传输到DSSD ClientCard,这个过程也绕开了Control Module上的x86 CPU。
通过libfloodAPI从客户端系统应用到DSSD D5设备的写操作
写入时的数据路径有些不同。其实DSSD的技术原理在业内早就不是秘密,去年我撰写的《NetBRIC S5:“另类”设计的全闪存阵列》一文中NetBRIC CEO周文就提到DSSD使用了PCIe MultiCast(多播)技术。数据进入I/O Module之后会同时写到2个Flash Module和Control Module,至于在这过程中RAID计算是如何进行的,我还需要查阅更多资料。
上图中我还画了个红圈,目的是省略了一张图——通过块驱动访问。那样数据流需要经过OS Kernel,多个步骤应该会带来一定的延时增加。
多种访问方式和缩短I/O路径
应用执行I/O到DSSD D5存储的访问方式汇总
在这张图中,左边是应用通过DSSD块驱动访问,中间是用libflood原生直接内存访问API,右边则是使用插件实现HDFS访问接口。
传统I/O栈vs. DSSDlibflood I/O栈
如上图,左边的传统I/O栈描述的硬件为SAS/SATA SSD,经过Kernel的访问方式;右边DSSD只需用User DMA Port替代了设备驱动、卷管理器和文件系统。I/O路径缩短成就了低延时高性能。
libfloodAPI与HDFS的整合对比其它HDFS方案
在HDFS的三种配置中,如果只是将SATA SSD换成PCIe SSD,显然不如DSSD HDFS插件来的彻底。那么PCIe SSD能否也写个这种插件呢?
不同对象类型定义、Fusion-io初衷再现
包含多种对象的“Volume 1” 和 “Volume 2”卷
上图中包含了几种对象,首先是卷,在卷里面又可以有若干目录、Key-value对象、Block对象和文件。再来看看下面这张图:
通过OID和目录路径的对象访问
DSSD的对象之间,应该也是有一个模拟的数状层级关系。比如对于文件系统打开目录A/B/C的操作,用对象机制执行就是open(vol, ID)。
下面是我从官方文档中翻译的一些内容,这些概念对于有些朋友估计都不陌生了。
•卷(Volume):可以动态绑定到特定客户端应用的一组对象,限制应用程序的逻辑存储视图。管理员规定动态地绑定一个应用到一个卷,其中包括一个根和池中的一个对象的子集。卷可以被原子化地删除(而不是说rm -rf)。
•目录:在一个卷内名称到对象的映射,就像一个POSIX文件系统目录。当应用程序想使用层级命名来查找对象时可以使用目录。目录是可选的;应用程序也可以使用它们的唯一标识符直接打开对象。
•文件:一个在任意偏移量支持POSIX兼容I/O并且在I/O对齐或者大小上没有限制,具有thinly-provisioned(自动精简配置,瘦供给)的字节流(byte-stream)。文件是一致性锁定的范围,并允许已有片段的读 - 修改 - 写。添加POSIX兼容对于文件对象来说与块对象相比确实降低了性能。
•块(Block):支持以片段大小对齐偏移量的NVMe标准I/O的thinly-provisioned字节流(byte-stream)。Block通过省略范围锁和只允许全片段读取或写入提供最大并发性和性能,并且不支持片段的读 - 修改 - 写。应用程序或块设备的消费者对管理并发访问完全负责。
•键值(Key-value):一个thinly-provisioned的字典映射任意Key的字节序列(最大65,535字节)到相应value的字节序列(最大1MB)。
DSSD D5对象池的一些主要特点包括:
•对象可在多个客户端之间共享
•卷可以包含所有的对象类型和所有支持的帧长度(FLENs),每个对象的配置FLENs从64B到32K
•诸如创建对象、删除对象,以及片段的读/写都是原生的原子操作
•对象是按需thinly-provisioned的
在这里证实了之前想到的一点。以前曾有朋友认为对象的访问效率没有块高,如果是传统意义上的对象存储,只支持固定大小的对象(比如32KB和1MB),put、get和delete操作,确实不以性能见长。而DSSD的对象存储实际上是采用了Key-value接口,同时支持比磁盘扇区(512byte)更小的分片——即I/O粒度,再加上libflood绕过Kernel的DMA访问方式,因此能够提供最好的性能。
当然闪存的最小物理写入单元是page,如今主流NAND应该是8KB/16KB,小于它的对象操作可以在内存/缓存中进行合并之类的处理。而64 bytes让我想起了在《从技术到应用:揭开3D XPoint Memory迷雾》一文中引用的一段话:
3年前我在《》一文中揭示过这样一个原理——“IO生成器将64Bytes(字节)的块通过Atomic Write API直接写入,注意这里的单个I/O大小比硬盘上的512Byte扇区和4KB的闪存页面都要小... 既然可以是顺序写,那么料想它能够将64字节的I/O在服务器内存中合并成适合闪存页面大小的4KB I/O再写入。”
管理界面:设备端和客户端CLI的分工
设备端CLI和客户端CLI执行位置
DSSD支持web图形管理方式,其CLI命令行界面被拆分成2个部分,位于设备端的ServiceModule只负责到卷一级的管理,而卷内部的管理操作在设备端的Flood Client CLI中进行。我之所以在这里介绍命令行,目的是有助于对前面一些概念的理解。
DSSD设备端CLI
上面几条命令,分别是创建、列表、显示和删除卷操作。
客户端CLI执行示例:在一个卷中创建一个对象并显示其属性
在这里我们可以看到,在卷中创建对象时需要指定类型(上图中为block)、对象大小(1G)和片段长度(4K),同时会生成一个对象ID。不过文档里可能有个小的排版错误——输入16k的Fragment输出却变成了4K?
总结与展望:下一个DSSD在哪里?
昨天我发了条微博,说EMC在NVMe存储方面又领先了。其实如果只是这一点——做个简单的NVMe块存储阵列是很容易被竞争对手追赶的。DSSD的功能讲了1、2年,然而我还没有听说短期内会有人发布功能相近的产品?毕竟EMC自己也还在教育市场的阶段。
走在前面带领大家吃螃蟹,这就是行业老大应该做的吧:)我想再借用赵军平老师文中的一句话,DSSD的面世标志着“进入In-Mem Processing 时代!”
参考资料:EMC白皮书《SOFTWARE ASPECTS OF THE EMC DSSD D5 RACK-SCALE FLASH STORAGEPLATFORM》
注:本文只代表作者个人观点,与任何组织机构无关,如有错误和不足之处欢迎批评指正。进一步交流技术,可以加我的QQ/微信:490834312。
重要提示:请在本公众号发布2天后,才能转载本文,有疑问请联系作者。尊重知识,请必须全文转载,并包括本行及如下二维码。
感谢您的阅读和支持!《企业存储技术》微信公众号:huangliang_storage
长按二维码可直接识别关注